package br.ufrj.dcc.dojo.jtrace;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.filechooser.FileFilter;

import br.ufrj.dcc.dojo.jtrace.texture.TextureMappingEnum;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class MainWindow {
	
	private static final String SINGLE_MESH = "Single Mesh";
	private static final String SINGLE_SPHERE = "Single Sphere";
	private static final String LOAD_TEXTURE = "Load texture";
	
	public static final int FRAME_W = 810;
	public static final int FRAME_H = 660;
	
	public static final int RENDER_W = 800;
	public static final int RENDER_H = 500;

	private JFrame frame;
	private JPanel panelRender;
	private TracerComponents tracerComponents;
	private JButton buttonLoadTexture;
	private JButton buttonLoadPly;
	private JComboBox cboxTextureMapping;
	
	private String textureFilename;
	private JCheckBox ckbBoudingBox;
	private JButton btnSingleSphere;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainWindow app = new MainWindow();
					app.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public MainWindow() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setResizable(false);
		frame.setTitle("JTrace - Filipe Xavier & Thales Pires");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(FRAME_W, FRAME_H);
		frame.getContentPane().setLayout(new BorderLayout(0, 0));
		
		JPanel panelTop = new JPanel();
		frame.getContentPane().add(panelTop, BorderLayout.NORTH);
		panelTop.setLayout(new GridLayout(0, 1, 0, 0));
		
		JPanel panelLoads = new JPanel();
		panelTop.add(panelLoads);
		
		buttonLoadPly = new JButton("Single PLY");
		buttonLoadPly.setHorizontalAlignment(SwingConstants.LEFT);
		panelLoads.add(buttonLoadPly);
		buttonLoadPly.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent event) {
				String file = MainWindow.class.getResource("MainWindow.class").getFile();
				JFileChooser fileChooser = new JFileChooser(file);
				fileChooser.setFileFilter(new FileFilter() {
					@Override
					public String getDescription() {
						return "Polygon File Format (.ply)";
					}
					@Override
					public boolean accept(File f) {
						return f.getName().toLowerCase().endsWith(".ply") || f.isDirectory();
					}
				});
				int returnValue = fileChooser.showOpenDialog(null);
				if (returnValue == JFileChooser.APPROVE_OPTION) {
					String filename = fileChooser.getSelectedFile().getAbsolutePath();
					try {
						tracerComponents = new SingleMesh(filename, RENDER_W, RENDER_H);
						tracerComponents.buildComponents();
						tracerComponents.getTracer().setBoudingBoxActive(ckbBoudingBox.isSelected());
						
						panelRender.removeAll();
						panelRender.add(tracerComponents.getTracerPanel());
						panelRender.validate();
						
						buttonLoadTexture.setEnabled(true);
						ckbBoudingBox.setEnabled(true);
						buttonLoadTexture.setText(LOAD_TEXTURE);
						buttonLoadPly.setText("Polygon: "+fileChooser.getSelectedFile().getName());
					} catch (Exception e) {
						e.printStackTrace();
						JOptionPane.showMessageDialog(frame, "Falha ao carregar .ply");
					}
				}
			}
		});
		
		btnSingleSphere = new JButton("Single Sphere");
		btnSingleSphere.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				try {
					tracerComponents = new SingleSphere(RENDER_W, RENDER_H);
					tracerComponents.buildComponents();
					tracerComponents.getTracer().setBoudingBoxActive(ckbBoudingBox.isSelected());
					
					panelRender.removeAll();
					panelRender.add(tracerComponents.getTracerPanel());
					panelRender.validate();
					
					buttonLoadTexture.setEnabled(true);
					ckbBoudingBox.setEnabled(true);
					buttonLoadTexture.setText(LOAD_TEXTURE);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		btnSingleSphere.setHorizontalAlignment(SwingConstants.LEFT);
		panelLoads.add(btnSingleSphere);
		
		JPanel panelOptions = new JPanel();
		panelTop.add(panelOptions);
		
		ckbBoudingBox = new JCheckBox("Bounding Box");
		ckbBoudingBox.setEnabled(false);
		ckbBoudingBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				boolean isChecked = e.getStateChange() == ItemEvent.SELECTED;
				tracerComponents.getTracer().setBoudingBoxActive(isChecked);
			}
		});
		
		buttonLoadTexture = new JButton("Texture");
		panelOptions.add(buttonLoadTexture);
		buttonLoadTexture.setEnabled(false);
		buttonLoadTexture.setHorizontalAlignment(SwingConstants.LEFT);
		
		buttonLoadTexture.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent event) {
				if (!buttonLoadTexture.isEnabled()) return;
				
				String currentDirectoryPath = MainWindow.class.getResource("MainWindow.class").getFile();
				JFileChooser fileChooser = new JFileChooser(currentDirectoryPath);
				fileChooser.setFileFilter(new FileFilter() {
					@Override
					public String getDescription() {
						return "Image Files (.jpg, .jpeg)";
					}
					@Override
					public boolean accept(File f) {
						String lowerCase = f.getName().toLowerCase();
						return lowerCase.endsWith(".jpg") || lowerCase.endsWith(".jpeg") ||f.isDirectory();
					}
				});
				
				int returnValue = fileChooser.showOpenDialog(null);
				if (returnValue == JFileChooser.APPROVE_OPTION) {
					textureFilename = fileChooser.getSelectedFile().getAbsolutePath();
					TextureMappingEnum textureMappingType = (TextureMappingEnum) cboxTextureMapping.getSelectedItem();
					try {
						tracerComponents.setTexture(textureFilename, textureMappingType);
						buttonLoadTexture.setText("Texture: "+fileChooser.getSelectedFile().getName());
						cboxTextureMapping.setEnabled(true);
					} catch (Exception e) {
						JOptionPane.showMessageDialog(frame, "Falha ao carregar textura.");
						e.printStackTrace();
					}
				}
			}
		});
		
		cboxTextureMapping = new JComboBox();
		panelOptions.add(cboxTextureMapping);
		cboxTextureMapping.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent event) {
				if (event.getStateChange() == ItemEvent.SELECTED) {
					System.out.println(event.getItem().toString());
					TextureMappingEnum textureMappingType = (TextureMappingEnum) event.getItem();
					try {
						tracerComponents.setTexture(textureFilename, textureMappingType);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		});
		cboxTextureMapping.setModel(new DefaultComboBoxModel(TextureMappingEnum.values()));
		cboxTextureMapping.setSelectedIndex(0);
		cboxTextureMapping.setEnabled(false);
		panelOptions.add(ckbBoudingBox);
		

		panelRender = new JPanel();
		frame.getContentPane().add(panelRender);
		
		panelRender.setLayout(new BoxLayout(panelRender, BoxLayout.X_AXIS));
	}

	public JComboBox getCboxTextureMapping() {
		return cboxTextureMapping;
	}
}